﻿using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding;

namespace OrderingFoot.Core.AspNetCore
{
    /// <summary>
    /// 控制器结果统一化过滤器
    /// </summary>
    internal class UnaryResultFilterAttribute : ResultFilterAttribute
    {
        /// <summary>
        /// OnResultExecuting
        /// </summary>
        public override void OnResultExecuting(ResultExecutingContext context)
        {
            if (!context.ModelState.IsValid)
            {
                var values = context.ModelState.Keys.SelectMany((string key) => context.ModelState[key].Errors.Select(delegate (ModelError e)
                {
                    var text = (!string.IsNullOrWhiteSpace(e.ErrorMessage)) ? e.ErrorMessage : e.Exception?.Message;
                    if (text != null && text.ToLower().Contains("value could not be converted"))
                    {
                        text = "字段" + key.TrimStart('$', '.') + "格式不正确";
                    }

                    return text;
                })).Distinct();
                var message = string.Join('；', values);
                context.Result = new ObjectResult(UnaryResult.Faild(-2, message));
            }

            if (context.ActionDescriptor is ControllerActionDescriptor controllerActionDescriptor
                && controllerActionDescriptor.MethodInfo.GetCustomAttributes(inherit: true).Any((object a) => a.GetType().Equals(typeof(DisabeUnaryResultAttribute))))
            {
                return;
            }

            if (context.Result is ObjectResult objectResult)
            {
                if (objectResult.Value == null)
                {
                    context.Result = new ObjectResult(UnaryResult.Succeed());
                }
                else if (!(objectResult.Value is UnaryResult))
                {
                    if (objectResult.DeclaredType == null)
                    {
                        context.Result = new ObjectResult(objectResult.Value);
                        return;
                    }

                    //var value = Activator.CreateInstance(typeof(UnaryResult<>).MakeGenericType(objectResult.DeclaredType), objectResult.Value);
                    var value = new UnaryResultObj { Data = objectResult.Value };
                    context.Result = new ObjectResult(value);
                }
            }
            else if (context.Result is EmptyResult)
            {
                context.Result = new ObjectResult(UnaryResult.Succeed());
            }
            else if (context.Result is ContentResult result)
            {
                context.Result = new ObjectResult(UnaryResult.Succeed(result.Content));
            }
            else if (context.Result is StatusCodeResult codeResult)
            {
                context.Result = new ObjectResult(UnaryResult.From(codeResult.StatusCode, string.Empty));
            }
        }
    }
}
